package com.neoden.notes;

import com.neoden.notes.models.NotesModel;
import com.neoden.notes.util.DialogHelpers;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;

public class NoteEditorActivity extends Activity {

	private static final String TAG = NoteEditorActivity.class.getName();
	
    public static final String EXTRA_ID = "id";
	public static final String EXTRA_LIST_ID = "listId";
    
	private static final String ORIGINAL_STATE = "originalState";
	private static final int MAX_DEFAULT_TITLE_LENGTH = 30;
    
	NotesModel mModel;
	
    private Note mNote;
    private Note mOriginalNote;
    private boolean mChanged = false;

    private static final int STATE_INVALID = -1;
    private static final int STATE_EDIT = 0;
    private static final int STATE_NEW = 1;
    private static final int STATE_REVERT = 2;
    private static final int STATE_EXPLICIT_SAVE = 3;

    private int mState = STATE_INVALID;
    
    private EditText mTextEditor;

	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_note_editor);
        
        mModel = new NotesModel(this);
        
        Intent intent = getIntent();
        if (intent.getAction() != null 
        		&& intent.getAction().equals(Intent.ACTION_SEND)) 
        {
        	// new note
        	mNote = new Note();
        	
        	if (intent.hasExtra(Intent.EXTRA_SUBJECT)) {
        		mNote.setTitle(intent.getStringExtra(Intent.EXTRA_SUBJECT));
        	}
        	else {
        		mNote.setTitle("");
        	}
        	if (intent.hasExtra(Intent.EXTRA_TEXT)) {
        		mNote.setNote(intent.getStringExtra(Intent.EXTRA_TEXT));
        	}
        	else {
        		mNote.setNote("");
        	}
        	
        	mNote.setCreatedTS(System.currentTimeMillis());
        	mNote.setModifiedTS(mNote.getCreatedTS());
        	mNote.setListId(mModel.getCurrentListId());
        	
        	mNote.setId(mModel.insertNote(mNote));
        	
        	mState = STATE_NEW;
        }
        else if (intent.hasExtra(EXTRA_ID)) {
        	// existing note
        	long id = intent.getLongExtra(EXTRA_ID, -1);
        	
        	if (id != -1) {
        		mNote = mModel.getNote(id);
        		if (mNote == null) {
        			Log.w(TAG, "Record not found: id = " + id);
        			finish();
        		}
        		else {
	        		mOriginalNote = new Note();
	        		mOriginalNote.consume(mNote);
	        		mState = STATE_EDIT;
        		}
        	}
        	else {
        		Log.w(TAG, "Bad id supplied");
        		finish();
        	}
        }
        else {
        	// activity launched in somewhat wrong way
        	Log.w(TAG, "Bad launch data");
        	finish();
        }
        
        if (mNote != null) {
            mTextEditor = (EditText)findViewById(R.id.note_editor);
    		mTextEditor.setText(mNote.getNote());
    		mTextEditor.addTextChangedListener(new TextWatcher() {

				public void onTextChanged(CharSequence s, int start,
						int before, int count) 
				{
					mChanged = true;
				}

				public void afterTextChanged(Editable s) {}
				public void beforeTextChanged(CharSequence s, int start,
						int count, int after) {}    			
    		});
        }
    	
    	if (savedInstanceState != null && savedInstanceState.containsKey(ORIGINAL_STATE)) {
    		mOriginalNote = (Note) savedInstanceState.getParcelable(ORIGINAL_STATE);
    	}
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_note_editor, menu);
        
        if (mState == STATE_NEW) {
        	menu.findItem(R.id.menu_cancel).setVisible(false);
        }
        
        return true;
    }

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		
		case R.id.menu_save:
			
			mState = STATE_EXPLICIT_SAVE;
			save();
			finish();
			return true;
			
		case R.id.menu_discard:
		
			DialogHelpers.confirm(this, null, getString(R.string.msg_delete_confirmation), 
					new DialogHelpers.OnConfirmListener() {
						public void onConfirm() {
							discard();
							finish();
						}
					}
			);
			return true;
			
		case R.id.menu_cancel:
			
			DialogHelpers.confirm(this, null, getString(R.string.msg_cancel_edit_confirmation), 
					new DialogHelpers.OnConfirmListener() {
						public void onConfirm() {
							revertToOriginal();
							finish();
						}
					}
			);
			return true;
			
		case R.id.menu_set_title:
			
			DialogHelpers.submitText(this, getString(R.string.title_list_title), mNote.getTitle(), 
					new DialogHelpers.OnSubmitTextListener() {
						public void onSubmitText(String text) {
							mNote.setTitle(text);
							mChanged = true;
						}
					});
			return true;			
			
		default:
			Log.w(TAG, "No handler for menu item: id = " + item.getItemId());
			return false;
		}
	}
	
	private void updateState() {
    	if (mNote != null) {
    		mNote.setNote(mTextEditor.getText().toString());
    		if (mNote.getTitle().equals("")) {
    			setDefaultNoteTitle(mNote);
    		}
    		mNote.setModifiedTS(System.currentTimeMillis());
    	}
	}
	
    private void save() {
    	if (mNote != null) {
    		int rowsAffected = mModel.updateNote(mNote);
    		if (rowsAffected != 1) {
    			Log.w(TAG, "Update affected " + rowsAffected + " rows");
    		}
    	}
    }
    
    private void setDefaultNoteTitle(Note note) {
		String title = "";
		
		String text = note.getNote().replace("\t", " ").trim(); 
		int length = text.length();
		
		title = text.substring(0, Math.min(MAX_DEFAULT_TITLE_LENGTH, length));
		
		int firstNewLine = title.indexOf("\n");
		if (firstNewLine != -1) {
			title = title.substring(0, firstNewLine);
		}
		else if (length > 30) {
			int lastSpace = title.lastIndexOf(" ");
			if (lastSpace > 0) {
				title = title.substring(0, lastSpace);
			}
		}
    	
		note.setTitle(title);
	}

	private void revertToOriginal() {
		// we were editing an existing note
		// revert to original data
		mNote.consume(mOriginalNote);
		save();
		mState = STATE_REVERT;
    }

    private void discard() {
    	if (mNote != null) {
    		mModel.deleteNote(mNote.getId());
    		mNote = null;
    	}
    }
    
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		
		if (mOriginalNote != null) {
			outState.putParcelable(ORIGINAL_STATE, mOriginalNote);
		}
	}
	
	@Override
	protected void onPause() {
		super.onPause();

		if (mNote != null) {
			if (isFinishing()) {
				if (mTextEditor.getText().length() == 0
						&& mNote.getTitle().length() == 0) 
				{
					discard();
				}
			}
			
			if (mState != STATE_REVERT && (mChanged || mState == STATE_EXPLICIT_SAVE)) {
				updateState();
				save();
			}
		}
	}
	
}
